/**
 * @file buttons.cpp
 * @brief 按钮输入处理模块实现
 */

#include "../include/buttons.h"

// 按钮引脚数组
const uint8_t buttonPins[BUTTON_TYPE_COUNT] = {
    BUTTON_MODE_PIN,
    BUTTON_UP_PIN,
    BUTTON_DOWN_PIN,
    BUTTON_ENTER_PIN
};

// 按钮状态数组
ButtonState buttonStates[BUTTON_TYPE_COUNT] = {BUTTON_IDLE};

// 按钮去抖动变量
uint32_t lastDebounceTime[BUTTON_TYPE_COUNT] = {0};
uint32_t debounceDelay = 50;  // 去抖动延迟时间（毫秒）

// 长按检测变量
uint32_t pressStartTime[BUTTON_TYPE_COUNT] = {0};
uint32_t longPressDelay = 1000;  // 长按时间阈值（毫秒）

// 按钮上一次读取状态
bool lastButtonState[BUTTON_TYPE_COUNT] = {HIGH};  // 假设按钮默认为高电平（上拉）

/**
 * @brief 初始化按钮
 */
void initButtons() {
    // 初始化按钮引脚
    for (int i = 0; i < BUTTON_TYPE_COUNT; i++) {
        pinMode(buttonPins[i], INPUT_PULLUP);
        buttonStates[i] = BUTTON_IDLE;
        lastButtonState[i] = HIGH;
        lastDebounceTime[i] = 0;
        pressStartTime[i] = 0;
    }
    
    // 初始化串口用于调试
    Serial.begin(115200);
#ifdef DEBUG_BUTTONS
    Serial.println("[BTN] 初始化完成");
#endif
}

/**
 * @brief 更新按钮状态
 */
void updateButtons() {
    uint32_t currentTime = millis();
    
    // 更新每个按钮的状态
    for (int i = 0; i < BUTTON_TYPE_COUNT; i++) {
        // 读取当前按钮状态
        bool reading = digitalRead(buttonPins[i]);
        
        // 如果按钮状态发生变化，重置去抖动计时器
        if (reading != lastButtonState[i]) {
            lastDebounceTime[i] = currentTime;
#ifdef DEBUG_BUTTONS
            Serial.printf("BTN%d:%s->%s\n", i, 
                lastButtonState[i] ? "HIGH" : "LOW",
                reading ? "HIGH" : "LOW");
#endif
            lastButtonState[i] = reading;
            
            // 立即更新按钮状态
            if (reading == LOW) {
                buttonStates[i] = BUTTON_PRESSED;
                pressStartTime[i] = currentTime;
            } else {
                buttonStates[i] = BUTTON_RELEASED;
            }
        }
        // 检查长按（仅在按钮保持按下状态时）
        else if (reading == LOW && (currentTime - pressStartTime[i]) > longPressDelay) {
            buttonStates[i] = BUTTON_LONG_PRESSED;
#ifdef DEBUG_BUTTONS
            Serial.printf("[BTN] %d长按\n", i);
#endif
            pressStartTime[i] = currentTime; // 重置计时器避免重复触发
        }
        
        // 保存当前按钮状态用于下次比较
        lastButtonState[i] = reading;
    }
}

/**
 * @brief 获取按钮状态
 * 
 * @param button 按钮类型
 * @return ButtonState 按钮状态
 */
ButtonState getButtonState(ButtonType button) {
    if (button < BUTTON_TYPE_COUNT) {
        return buttonStates[button];
    }
    return BUTTON_IDLE;
}

/**
 * @brief 检查按钮是否刚被按下
 * 
 * @param button 按钮类型
 * @return true 按钮刚被按下
 * @return false 按钮未被按下
 */
bool isButtonPressed(ButtonType button) {
    if (button < BUTTON_TYPE_COUNT) {
        bool result = (buttonStates[button] == BUTTON_PRESSED);
        if (result) {
            // 读取后重置状态，避免重复触发
            buttonStates[button] = BUTTON_IDLE;
        }
        return result;
    }
    return false;
}

/**
 * @brief 检查按钮是否刚被释放
 * 
 * @param button 按钮类型
 * @return true 按钮刚被释放
 * @return false 按钮未被释放
 */
bool isButtonReleased(ButtonType button) {
    if (button < BUTTON_TYPE_COUNT) {
        bool result = (buttonStates[button] == BUTTON_RELEASED);
        if (result) {
            // 读取后重置状态，避免重复触发
            buttonStates[button] = BUTTON_IDLE;
        }
        return result;
    }
    return false;
}

/**
 * @brief 检查按钮是否被长按
 * 
 * @param button 按钮类型
 * @return true 按钮被长按
 * @return false 按钮未被长按
 */
bool isButtonLongPressed(ButtonType button) {
    if (button < BUTTON_TYPE_COUNT) {
        bool result = (buttonStates[button] == BUTTON_LONG_PRESSED);
        if (result) {
            // 读取后重置状态，避免重复触发
            buttonStates[button] = BUTTON_IDLE;
        }
        return result;
    }
    return false;
}

/**
 * @brief 重置按钮状态
 * 
 * @param button 按钮类型
 */
void resetButtonState(ButtonType button) {
    if (button < BUTTON_TYPE_COUNT) {
        buttonStates[button] = BUTTON_IDLE;
    }
}